// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
import * as vscode from 'vscode';

export class paramDeclaration {
	constructor(public paramName:any) {
		this.paramName = paramName;
	}
}

export function getParameterText(paramList: paramDeclaration[], padding: string, docstyle: string): string {
	var textToInsert: string = "";
	textToInsert = textToInsert + '"""';
	if (docstyle == 'google') {
		textToInsert = textToInsert + '\ndocstring here\n';
		paramList.forEach(element => {
			if (element.paramName != '') {
				textToInsert = textToInsert + padding + ':param ';
				textToInsert = textToInsert + element.paramName + ': \n';
			}
		});
	}
	else if (docstyle == 'numpy') {
        textToInsert = textToInsert + 'Set docstring here.\n';
		textToInsert = textToInsert + '\nParameters';
		textToInsert = textToInsert + '\n----------\n';
		paramList.forEach(element => {
			if (element.paramName != '') {
				textToInsert = textToInsert + element.paramName + ': \n';
			}
		});
        textToInsert = textToInsert + '\nReturns\n';
        textToInsert = textToInsert + '-------\n\n';
	}
	textToInsert = textToInsert + '"""';

	return textToInsert;
}

//Assumes that the string passed in starts with ( and continues to ) and does not contain any comments or white space
export function getParameters(text: string): paramDeclaration[] {
	var paramList: paramDeclaration[] = [];
	//Start by looking for the function name declaration
	var index = 0;
	text = text.replace(/\s/g, '');
	//Now we are at the first non whitespace character
	//if it is not a '(' then this is not a valid function declaration
	if (text.charAt(index) == '(') {
		//count the number of matching opening and closing braces. Keep parsing until 0
		var numBraces = 1;
		index++;
		while ((numBraces != 0) && (index != text.length)) {
					
			//Now we are at a non whitespace character. Assume it is the parameter name
			var name: string = '';
			//while ((text.charAt(index) != ':') && (text.charAt(index) != ',') && (text.charAt(index) != ')') && (index < text.length)) {
			while ((text.charAt(index) != ',') && (text.charAt(index) != ')') && (index < text.length)) {
				name = name + text.charAt(index);
				index++;
			}
			if (index < text.length) {		
				//Now we are at a : or a ',', skip then read until a , to get the param type
				var type: string = '';
				//we have a type to process
				if (text.charAt(index) == '(') {
					var startNumBraces = numBraces;
					numBraces++;
					type = type + text.charAt(index);
					index++;
					//we have encountered a function type
					//read all the way through until the numBraces = startNumBraces
					while ((numBraces != startNumBraces) && (index < text.length)) {
						if (text.charAt(index) == ')') {
							numBraces--;
						}
						else if (text.charAt(index) == '(') {
							numBraces++;
						}
						type = type + text.charAt(index);
						index++;
					}
					if (index < text.length) {
						//Now read up to either a , or a )
						while ((text.charAt(index) != ',') && (text.charAt(index) != ')')) {
							type = type + text.charAt(index);
							index++;
						}
						if (text.charAt(index) == ')') {
							numBraces--;
						}
					}
				}
				else {
					while ((text.charAt(index) != ',') && (text.charAt(index) != ')') && (index != text.length)) {
						type = type + text.charAt(index);
						index++;
					}
					if (text.charAt(index) == ')') {
						numBraces--;
					}
				}
				paramList.push(new paramDeclaration(name));
				if (index < text.length) {
					index++;
				}
			}
		}

	}

	return paramList;
}

// this method is called when your extension is activated
// your extension is activated the very first time the command is executed
export function activate(context: vscode.ExtensionContext) {

	// Use the console to output diagnostic information (console.log) and errors (console.error)
	// This line of code will only be executed once when your extension is activated
		console.log('Congratulations, your extension "pydoczt" is now active!');

	// The command has been defined in the package.json file
	// Now provide the implementation of the command with registerCommand
	// The commandId parameter must match the command field in package.json
	let disposable = vscode.commands.registerCommand('extension.pydoczt', () => {
		// The code you place here will be executed every time your command is executed

		// Display a message box to the user
		//vscode.window.showInformationMessage('Hello World!');
		const activetext=vscode.window.activeTextEditor;
		if( !activetext){
			return;
		}
		let lang = activetext.document.languageId;
		if ((lang == "python" )) {
			let selection = activetext.selection;
			let startLine = selection.start.line - 1;
			//var selectedText = activetext.document.getText(selection);
			let selectedText:string = activetext.document.lineAt(selection.start.line).text;
			let lineLen=1;
			for(let i=1;i<10 && i<=activetext.document.lineCount;i++){
				if(selectedText.indexOf(")")>0){
					lineLen=i;
					break;
				}else{
					selectedText+=activetext.document.lineAt(selection.start.line+i).text;
				}
			}
			
			let firstBraceIndex = selectedText.indexOf('(');
			selectedText = selectedText.slice(firstBraceIndex);
			let params: paramDeclaration[] = getParameters(selectedText);

			if (params.length > 0) {
				let docstyle: string = vscode.workspace.getConfiguration().pydocs.style;
				let spaces_enabled: any = activetext.options.insertSpaces;
				let tabSize : any = activetext.options.tabSize;
				let padding: string = ''
				if ( spaces_enabled == true ){
					padding = Array(tabSize +1).join(' ');
				}
				else {
					padding = '\t';
				}
				let textToInsert = getParameterText(params, padding, docstyle);
				activetext.edit((editBuilder: vscode.TextEditorEdit) => {
					let pos:vscode.Position;
					pos = new vscode.Position(startLine+lineLen+1, 0); 
					let line:string = activetext.document.lineAt(selection.start.line).text;
					let firstNonWhiteSpace :number = activetext.document.lineAt(selection.start.line).firstNonWhitespaceCharacterIndex;
					let stringToIndent: string = '';

					for (let i = 0; i < firstNonWhiteSpace; i++) {
						if (line.charAt(i) == '\t') {
							stringToIndent = stringToIndent + '\t';
						}
						else if (line.charAt(i) == ' ') {
							stringToIndent = stringToIndent + ' ';
						}
					}
					stringToIndent = padding + stringToIndent;
					let textarr=textToInsert.split("\n");
					for(let i=0;i<textarr.length;i++){
						textarr[i]=stringToIndent+textarr[i];
					}
					textToInsert=textarr.join("\n")+"\n";
					editBuilder.insert(pos, textToInsert);

				}).then(() => {
					
				});
			}
		}
	});

	context.subscriptions.push(disposable);
}

// this method is called when your extension is deactivated
export function deactivate() {}
